+2005-09-08 Øyvind Kolås <pippin@gimp.org>
+
+ * babl/base/type-float.c:
+ * babl/base/type-u16.c:
+ * babl/base/type-u8.c: s/"linear"/"plane"/
+ * babl/base/Makefile.am,
+ * babl/base/babl-base.c,
+ * babl/base/type-u32.c: new type.
+ * extensions/CIE-Lab.c:
+ * extensions/Makefile.in: changes needed (for not yet added) lcms
+ extension.
+ * tests/Makefile.am: added new test.
+ * tests/conversions.c: new test to check fast paths against reference
+ fish.
+
2005-09-08 Øyvind Kolås <pippin@gimp.org>
Made simple fishes work in the core.
* babl/babl-introspect.c: (each_introspect):
* babl/babl-model.c: (babl_model_new):
* babl/babl-core.c: (babl_core_init): s/linear/plane/
+ * tests/babl_class_name.c: update according to class changes.
2005-09-08 Øyvind Kolås <pippin@gimp.org>
registered data structures.
* docs/graphics/Makefile.am: added web target, and .SILENT option.
* docs/Makefile.am: added .SILENT option.
+ * configure.ac: added website location.
2005-09-01 Michael Schumacher <schumaml@cvs.gnome.org>
+
h_sources = \
babl-base.h
type-float.c \
type-u8.c \
type-u16.c \
+ type-u32.c \
model-rgb.c \
model-gray.c \
model-ycbcr.c
void babl_base_type_float (void);
void babl_base_type_u8 (void);
void babl_base_type_u16 (void);
+void babl_base_type_u32 (void);
static void
types (void)
babl_base_type_float ();
babl_base_type_u8 ();
babl_base_type_u16 ();
+ babl_base_type_u32 ();
}
/*
babl_conversion_new (
babl_type_id (BABL_FLOAT),
babl_type_id (BABL_DOUBLE),
- "linear", convert_float_double,
+ "plane", convert_float_double,
NULL
);
babl_conversion_new (
babl_type_id (BABL_DOUBLE),
babl_type_id (BABL_FLOAT),
- "linear", convert_double_float,
+ "plane", convert_double_float,
NULL
);
}
*/
#include <string.h>
+#include <stdint.h>
#include <assert.h>
#include "babl.h"
static inline long
-convert_double_u16_scaled (double min_val,
- double max_val,
- unsigned short min,
- unsigned short max,
- void *src,
- void *dst,
- int src_pitch,
- int dst_pitch,
- long n)
+convert_double_u16_scaled (double min_val,
+ double max_val,
+ uint16_t min,
+ uint16_t max,
+ void *src,
+ void *dst,
+ int src_pitch,
+ int dst_pitch,
+ long n)
{
while (n--)
{
- double dval = *(double *) src;
- unsigned short u16val;
+ double dval = *(double *) src;
+ uint16_t u16val;
if (dval < min_val)
u16val = min;
else
u16val = (dval-min_val) / (max_val-min_val) * (max-min) + min;
- *(unsigned short *) dst = u16val;
+ *(uint16_t *) dst = u16val;
dst += dst_pitch;
src += src_pitch;
}
}
static inline long
-convert_u16_double_scaled (double min_val,
- double max_val,
- unsigned short min,
- unsigned short max,
- void *src,
- void *dst,
- int src_pitch,
- int dst_pitch,
- long n)
+convert_u16_double_scaled (double min_val,
+ double max_val,
+ uint16_t min,
+ uint16_t max,
+ void *src,
+ void *dst,
+ int src_pitch,
+ int dst_pitch,
+ long n)
{
while (n--)
{
- int u16val = *(unsigned short*) src;
+ int u16val = *(uint16_t*) src;
double dval;
if (u16val < min)
src, dst, src_pitch, dst_pitch, n);\
}
-MAKE_CONVERSIONS(u16,0.0,1.0,0,0xffff);
+MAKE_CONVERSIONS(u16,0.0,1.0,0,UINT16_MAX);
void
babl_base_type_u16 (void)
babl_conversion_new (
babl_type_id (BABL_U16),
babl_type_id (BABL_DOUBLE),
- "linear", convert_u16_double,
+ "plane", convert_u16_double,
NULL
);
babl_conversion_new (
babl_type_id (BABL_DOUBLE),
babl_type_id (BABL_U16),
- "linear", convert_double_u16,
+ "plane", convert_double_u16,
NULL
);
}
--- /dev/null
+/* babl - dynamically extendable universal pixel conversion library.
+ * Copyright (C) 2005, Øyvind Kolås.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <stdint.h>
+#include <assert.h>
+
+#include "babl.h"
+#include "babl-ids.h"
+
+static inline long
+convert_double_u32_scaled (double min_val,
+ double max_val,
+ uint32_t min,
+ uint32_t max,
+ void *src,
+ void *dst,
+ int src_pitch,
+ int dst_pitch,
+ long n)
+{
+ while (n--)
+ {
+ double dval = *(double *) src;
+ uint32_t u32val;
+
+ if (dval < min_val)
+ u32val = min;
+ else if (dval > max_val)
+ u32val = max;
+ else
+ u32val = (dval-min_val) / (max_val-min_val) * (max-min) + min;
+
+ *(uint32_t *) dst = u32val;
+ dst += dst_pitch;
+ src += src_pitch;
+ }
+ return n;
+}
+
+static inline long
+convert_u32_double_scaled (double min_val,
+ double max_val,
+ uint32_t min,
+ uint32_t max,
+ void *src,
+ void *dst,
+ int src_pitch,
+ int dst_pitch,
+ long n)
+{
+ while (n--)
+ {
+ int u32val = *(uint32_t*) src;
+ double dval;
+
+ if (u32val < min)
+ dval = min_val;
+ else if (u32val > max)
+ dval = max_val;
+ else
+ dval = (u32val-min) / (double)(max-min) * (max_val-min_val) + min_val;
+
+ (*(double *) dst) = dval;
+ dst += dst_pitch;
+ src += src_pitch;
+ }
+ return n;
+}
+
+#define MAKE_CONVERSIONS(name, min_val, max_val, min, max) \
+static long \
+convert_##name##_double (void *src, \
+ void *dst, \
+ int src_pitch, \
+ int dst_pitch, \
+ long n) \
+{ \
+ return convert_u32_double_scaled (min_val, max_val, min, max, \
+ src, dst, src_pitch, dst_pitch, n);\
+} \
+static long \
+convert_double_##name (void *src, \
+ void *dst, \
+ int src_pitch, \
+ int dst_pitch, \
+ long n) \
+{ \
+ return convert_double_u32_scaled (min_val, max_val, min, max, \
+ src, dst, src_pitch, dst_pitch, n);\
+}
+
+MAKE_CONVERSIONS(u32,0.0,1.0,0,UINT32_MAX);
+
+void
+babl_base_type_u32 (void)
+{
+ babl_type_new (
+ "u32",
+ "id", BABL_U32,
+ "bits", 32,
+ NULL);
+
+ babl_conversion_new (
+ babl_type_id (BABL_U32),
+ babl_type_id (BABL_DOUBLE),
+ "plane", convert_u32_double,
+ NULL
+ );
+
+ babl_conversion_new (
+ babl_type_id (BABL_DOUBLE),
+ babl_type_id (BABL_U32),
+ "plane", convert_double_u32,
+ NULL
+ );
+}
babl_conversion_new (
babl_type_id (BABL_U8),
babl_type_id (BABL_DOUBLE),
- "linear", convert_u8_double,
+ "plane", convert_u8_double,
NULL
);
babl_conversion_new (
babl_type_id (BABL_DOUBLE),
babl_type_id (BABL_U8),
- "linear", convert_double_u8,
+ "plane", convert_double_u8,
NULL
);
babl_conversion_new (
babl_type_id (BABL_U8_LUMA),
babl_type_id (BABL_DOUBLE),
- "linear", convert_u8_luma_double,
+ "plane", convert_u8_luma_double,
NULL
);
babl_conversion_new (
babl_type_id (BABL_DOUBLE),
babl_type_id (BABL_U8_LUMA),
- "linear", convert_double_u8_luma,
+ "plane", convert_double_u8_luma,
NULL
);
babl_conversion_new (
babl_type_id (BABL_U8_CHROMA),
babl_type_id (BABL_DOUBLE),
- "linear", convert_u8_chroma_double,
+ "plane", convert_u8_chroma_double,
NULL
);
babl_conversion_new (
babl_type_id (BABL_DOUBLE),
babl_type_id (BABL_U8_CHROMA),
- "linear", convert_double_u8_chroma,
+ "plane", convert_double_u8_chroma,
NULL
);
}
babl_conversion_new (
babl_type ("CIE u8 L"),
babl_type ("double"),
- "linear", convert_u8_l_double,
+ "plane", convert_u8_l_double,
NULL
);
babl_conversion_new (
babl_type ("double"),
babl_type ("CIE u8 L"),
- "linear", convert_double_u8_l,
+ "plane", convert_double_u8_l,
NULL
);
babl_conversion_new (
babl_type ("CIE u8 ab"),
babl_type ("double"),
- "linear", convert_u8_ab_double,
+ "plane", convert_u8_ab_double,
NULL
);
babl_conversion_new (
babl_type ("double"),
babl_type ("CIE u8 ab"),
- "linear", convert_double_u8_ab,
+ "plane", convert_double_u8_ab,
NULL
);
}
babl_conversion_new (
babl_type ("CIE u16 L"),
babl_type ("double"),
- "linear", convert_u16_l_double,
+ "plane", convert_u16_l_double,
NULL
);
babl_conversion_new (
babl_type ("double"),
babl_type ("CIE u16 L"),
- "linear", convert_double_u16_l,
+ "plane", convert_double_u16_l,
NULL
);
babl_conversion_new (
babl_type ("CIE u16 ab"),
babl_type ("double"),
- "linear", convert_u16_ab_double,
+ "plane", convert_u16_ab_double,
NULL
);
babl_conversion_new (
babl_type ("double"),
babl_type ("CIE u16 ab"),
- "linear", convert_double_u16_ab,
+ "plane", convert_double_u16_ab,
NULL
);
}
CIE-Lab.so: CIE-Lab.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lm
+lcms.so: lcms.c
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< `pkg-config lcms --cflags --libs`
cp $(CFILES) $(Makefile.in) $$distdir
dvi:
+check:
#playing along with automake
.PRECIOUS: Makefile
rgb_to_ycbcr \
srgb_to_lab_u8 \
sanity \
+ conversions \
types \
models \
+ foo \
babl_class_name
TESTS_ENVIRONMENT = BABL_PATH=$(top_builddir)/extensions
sanity_SOURCES = sanity.c
types_SOURCES = types.c
models_SOURCES = models.c
+foo_SOURCES = foo.c
AM_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/babl
--- /dev/null
+/* perform a symmetricality of conversion test on a set of randomized
+ * RGBA data */
+
+#include <stdlib.h>
+#include <math.h>
+#include "babl-internal.h"
+
+int OK=1;
+
+#define pixels 102400
+#define TOLERANCE 0.001
+
+double test[pixels * 4];
+
+double r_interval (double min, double max)
+{
+ long int rand_i = random ();
+ double ret;
+ ret = (double) rand_i / RAND_MAX;
+ ret*=(max-min);
+ ret+=min;
+ return ret;
+}
+
+void test_init (void)
+{
+ double r_min = 0.0,
+ r_max = 1.0,
+ g_min = 0.0,
+ g_max = 1.0,
+ b_min = 0.0,
+ b_max = 1.0,
+ a_min = 0.0,
+ a_max = 1.0;
+ int i;
+ double r,g,b,a;
+ for (i=0;i<pixels;i++)
+ {
+ r=r_interval(r_min, r_max);
+ g=r_interval(g_min, g_max);
+ b=r_interval(b_min, b_max);
+ a=r_interval(a_min, a_max);
+ test [i*4 + 0]=r;
+ test [i*4 + 1]=g;
+ test [i*4 + 2]=b;
+ test [i*4 + 3]=a;
+ }
+}
+
+static Babl *reference_format (void)
+{
+ static Babl *self = NULL;
+
+ if (!self)
+ self = babl_format_new (
+ babl_model ("RGBA"),
+ babl_type ("double"),
+ babl_component ("R"),
+ babl_component ("G"),
+ babl_component ("B"),
+ babl_component ("A"),
+ NULL);
+ return self;
+}
+
+static void
+validate_conversion (BablConversion *conversion)
+{
+ Babl *fmt_rgba_double = reference_format ();
+ Babl *fmt_source = BABL(conversion->source);
+ Babl *fmt_destination = BABL(conversion->destination);
+
+ void *source;
+ void *destination;
+ double *destination_rgba_double;
+ void *ref_destination;
+ double *ref_destination_rgba_double;
+
+ source = babl_calloc (pixels, fmt_source->format.bytes_per_pixel);
+ destination = babl_calloc (pixels, fmt_destination->format.bytes_per_pixel);
+ ref_destination = babl_calloc (pixels, fmt_destination->format.bytes_per_pixel);
+ destination_rgba_double = babl_calloc (pixels, fmt_rgba_double->format.bytes_per_pixel);
+ ref_destination_rgba_double = babl_calloc (pixels, fmt_rgba_double->format.bytes_per_pixel);
+
+ babl_process (babl_fish_reference (fmt_rgba_double, fmt_source),
+ test, source, pixels);
+ babl_process (babl_fish_simple (conversion),
+ source, destination, pixels);
+
+ babl_process (babl_fish_reference (fmt_source, fmt_destination),
+ source, ref_destination, pixels);
+
+ babl_process (babl_fish_reference (fmt_destination, fmt_rgba_double),
+ ref_destination, ref_destination_rgba_double, pixels);
+ babl_process (babl_fish_reference (fmt_destination, fmt_rgba_double),
+ destination, destination_rgba_double, pixels);
+
+ {
+ int i;
+ int log=0;
+
+ for (i=0;i<pixels;i++)
+ {
+ int j;
+ for (j=0;j<4;j++)
+ if (fabs (destination_rgba_double[i*4+j] -
+ ref_destination_rgba_double[i*4+j])>TOLERANCE)
+ {
+ if (!log)
+ log=1;
+ OK=0;
+ }
+ if (log && log < 5)
+ {
+ babl_log ("%s", conversion->instance.name);
+ babl_log ("\ttest: %2.3f %2.3f %2.3f %2.3f", test [i*4+0],
+ test [i*4+1],
+ test [i*4+2],
+ test [i*4+3]);
+ babl_log ("\tconversion: %2.3f %2.3f %2.3f %2.3f", destination_rgba_double [i*4+0],
+ destination_rgba_double [i*4+1],
+ destination_rgba_double [i*4+2],
+ destination_rgba_double [i*4+3]);
+ babl_log ("\tref_conversion: %2.3f %2.3f %2.3f %2.3f", ref_destination_rgba_double [i*4+0],
+ ref_destination_rgba_double [i*4+1],
+ ref_destination_rgba_double [i*4+2],
+ ref_destination_rgba_double [i*4+3]);
+ log++;
+ OK=0;
+ }
+ }
+ }
+
+
+ babl_free (source);
+ babl_free (destination);
+ babl_free (destination_rgba_double);
+ babl_free (ref_destination);
+ babl_free (ref_destination_rgba_double);
+}
+
+static int
+each_conversion (Babl *babl,
+ void *userdata)
+{
+ Babl *source = BABL(babl->conversion.source);
+ Babl *destination = BABL(babl->conversion.destination);
+
+ if (source->instance.id != BABL_RGBA &&
+ destination->instance.id != BABL_RGBA &&
+ source->instance.id != BABL_DOUBLE &&
+ destination->instance.id != BABL_DOUBLE &&
+ source->class_type == BABL_FORMAT &&
+ destination->class_type == BABL_FORMAT)
+ {
+ validate_conversion ((BablConversion*)babl);
+ }
+ return 0;
+}
+
+int main (void)
+{
+ babl_init ();
+ test_init ();
+
+ babl_set_extender (babl_extension_quiet_log ());
+ babl_conversion_each (each_conversion, NULL);
+
+ babl_destroy ();
+
+ return !OK;
+}